﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Mani.Common.Security;
using RastinArgham.CRM.Business;
using Mani.Common;
using Mani.Common.WorkflowEngine;
using System.Collections.ObjectModel;

namespace RastinArgham.CRM.Web
{
    public partial class order_product : System.Web.UI.Page
    {
        public ISecurityManager securityManager { get; set; }
        public CRMRepository crmRepository { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (securityManager == null)
            {
                securityManager = new SecurityManager();
                securityManager.authProvider = new WebAuthorizationProvider();
            }

            if (crmRepository == null)
                crmRepository = new CRMRepository();

            if (!securityManager.IsActionPermitted("order_products"))
                Response.Redirect("~/access_denied.aspx");

            pnlOrderProduct.Visible = securityManager.IsActionPermitted("submit_product_order");

            if (!Page.IsPostBack)
            {
                LoadProducts();
                LoadOrders();
                txtOrderDate.Text = DateTime.Now.ToJalali();

                if (!String.IsNullOrEmpty(Request.QueryString["OrderId"]))
                {
                    LoadOrderId();
                }
            }
        }

        private void LoadProducts()
        {
            if (String.IsNullOrEmpty(Request.QueryString["id"]))
                return;

            Contact c = crmRepository.GetContactById(Convert.ToInt32(Request.QueryString["id"]));

            ddlProducts.DataSource = crmRepository.GetProductsByProvince(c.City.ProvinceId);
            ddlProducts.DataBind();
        }

        private void LoadOrders()
        {
            if ( String.IsNullOrEmpty(Request.QueryString["id"]) )
                return;

            Contact c = crmRepository.GetContactById(Convert.ToInt32(Request.QueryString["id"]));
            ContactInfo1.contact = c;
            ContactInfo1.DataBind();

            List<Order> orders = crmRepository.GetOrdersByContact(c.ContactId);

            if (orders.Count == 0)
                return;

            Guid currentUserId = securityManager.authProvider.GetCurrentUser().UserId;
            List<Guid> myAccountManagers = crmRepository.FindMyAccountManagers(currentUserId);

            if (!securityManager.IsActionPermitted("all_contacts") && c.AccountOwner != currentUserId && c.AccountManagerId != currentUserId & !myAccountManagers.Contains(c.AccountManagerId))
                Response.Redirect("~/access_denied.aspx");


            gvOrders.DataSource = orders.Where(o => o.ProductId.HasValue).ToList();
            gvOrders.DataBind();
        }

        private void LoadOrderId()
        {
            if (!securityManager.IsActionPermitted("edit_stock_items"))
                Response.Redirect("~/access_denied.aspx");

            int orderId = -1;

            if (!Int32.TryParse(Request.QueryString["OrderId"], out orderId))
                return;

            Order o = crmRepository.GetOrderById(orderId);

            StockItem s = o.StockItems.FirstOrDefault();

            if (s != null)
            {
                txtPaymentCode.Text = s.PaymentCode;
                txtPassword.Text = s.Password;
                txtISDN.Text = s.ISDN;
                txtDeptCode.Text = s.DeptCode;
                txtSubID.Text = s.SubID;
                txtSerial.Text = s.SerialNumber;
            }

            lblTitle.Text = "تغییر مشخصات مودم";
            btnSubmitOrder.Text = "ذخیره تغییرات";
            
            ddlProducts.ClearSelection();
            ddlProducts.Items.FindByValue(o.ProductId.ToString()).Selected = true;
            ddlProducts.Enabled = false;
            
            txtOrderDate.Text = o.OrderDate.ToJalali();
            txtOrderDate.Enabled = false;
            txtOrderId.Text = orderId.ToString();
            txtOrderId.Enabled = false;
        }

        protected void btnSubmitOrder_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(Request.QueryString["id"]))
                return;

            if (String.IsNullOrEmpty(txtOrderId.Text))
                New();
            else
                Update();
            
            LoadOrders();
            ClearForm();
        }

        private void New()
        {
            StockItem s = null;

            if (!String.IsNullOrEmpty(txtSerial.Text))
            {
                s = crmRepository.GetStockItemBySerial(txtSerial.Text);

                if (s == null)
                {
                    UIHelper.ClientAlert(this, "کالای مورد نظر در انبار موجود نیست");
                    return;
                }

                if (s.Status != 10 && s.Status != 20)
                {
                    UIHelper.ClientAlert(this, "کالای مورد نظر به شخص دیگری تخصیص داده شده است");
                    return;
                }
            }


            Contact c = crmRepository.GetContactById(Convert.ToInt32(Request.QueryString["id"]));
            Product p = crmRepository.GetProductById(Convert.ToInt32(ddlProducts.SelectedValue));

            Order o = new Order();
            o.Product = p;
            o.ProductId = p.ProductId;
            o.AccountManagerId = c.AccountManagerId;
            o.Contact = c;
            o.ContactId = c.ContactId;
            o.Price = p.Price;
            o.Quantity = 1;
            o.TaxPercent = p.TaxPercent;
            o.OrderDate = txtOrderDate.Text.ToDateTime().Value;

            Guid OperatorId = securityManager.authProvider.GetCurrentUser().UserId;
            o.OperatorId = OperatorId;

            crmRepository.NewOrder(o);

            if (s != null)
            {
                s.Order = o;
                s.LastUpdate = DateTime.Now;
                s.OperatorId = OperatorId;
                s.Status = 30;
                s.PaymentCode = txtPaymentCode.Text;
                s.Password = txtPassword.Text;
                s.ISDN = txtISDN.Text;
                s.DeptCode = txtDeptCode.Text;
                s.SubID = txtSubID.Text;
            }

            crmRepository.Save();

            WorkflowBasic wf = WorkflowFactory.Create(typeof(ProductOrderWorkflow), o.OrderId, OperatorId);
            o.WorkflowInstanceId = wf.InstanceId;

            crmRepository.Save();


            UIHelper.ClientAlert(this, "سفارش با موفقیت ذخیره شد");
            UIHelper.ClientRedirect(this, "order_services.aspx?id=" + o.ContactId.ToString());
        }

        private void Update()
        {
            int orderId = -1;

            if (!Int32.TryParse(txtOrderId.Text, out orderId))
                return;

            Order o = crmRepository.GetOrderById(orderId);

            if (!String.IsNullOrEmpty(txtSerial.Text))
            {

                StockItem s = crmRepository.GetStockItemBySerial(txtSerial.Text);

                if (!String.IsNullOrEmpty(o.Serial) && o.Serial != txtSerial.Text)
                {
                    StockItem oldStockItem = o.StockItems.FirstOrDefault();
                    oldStockItem.Order = null;
                    oldStockItem.OrderId = null;
                    oldStockItem.LastUpdate = DateTime.Now;
                    oldStockItem.OperatorId = securityManager.authProvider.GetCurrentUser().UserId;
                    oldStockItem.Status = 10; 
                }

                if (s == null)
                {
                    UIHelper.ClientAlert(this, "کالای مورد نظر در انبار موجود نیست");
                    return;
                }

                if (s.ProductId != o.ProductId)
                {
                    UIHelper.ClientAlert(this, "نوع کالای سریال مورد نظر با نوع کالای سفارش هماهنگی ندارد");
                    return;
                }

                if (s.OrderId.HasValue && s.OrderId != orderId)
                {
                    UIHelper.ClientAlert(this, "کالای مورد نظر به شخص دیگری تخصیص داده شده است");
                    return;
                }


                s.PaymentCode = txtPaymentCode.Text;
                s.Password = txtPassword.Text;
                s.ISDN = txtISDN.Text;
                s.DeptCode = txtDeptCode.Text;
                s.SubID = txtSubID.Text;

                s.Order = o;
                s.LastUpdate = DateTime.Now;
                s.OperatorId = securityManager.authProvider.GetCurrentUser().UserId;
                s.Status = 30;
            }

            crmRepository.Save();
            UIHelper.ClientAlert(this, "تغییرات با موفقیت ذخیره شد");
        }

        private void ClearForm()
        {
            txtOrderDate.Enabled = true;
            txtOrderDate.Text = DateTime.Now.ToJalali();
            txtSerial.Text = String.Empty;
            txtSerial.Enabled = true;
            ddlProducts.ClearSelection();
            txtOrderId.Text = String.Empty;
            lblTitle.Text = "سفارش کالا";
            btnSubmitOrder.Text = "سفارش";

            txtPaymentCode.Text = String.Empty;
            txtPassword.Text = String.Empty;
            txtISDN.Text = String.Empty;
            txtDeptCode.Text = String.Empty;
            txtSubID.Text = String.Empty;
        }

        protected void gvOrders_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType != DataControlRowType.DataRow)
                return;

            int orderId = Convert.ToInt32(gvOrders.DataKeys[e.Row.RowIndex].Value);
            Order o = crmRepository.GetOrderById(orderId);

            WorkflowBasic wf = WorkflowFactory.Load(o.WorkflowInstanceId.Value);

            string[] roles = securityManager.authProvider.GetCurrentUser().aspnet_Roles.Select( r => r.RoleName ).ToArray(); 
            ReadOnlyCollection<String> events = wf.GetPossibleEvents(roles);

            int i = 1;

            foreach (var item in events)
            {
                LinkButton link = (LinkButton)e.Row.FindControl("lbLink" + i.ToString());
                if (link != null)
                {
                    link.Visible = true;
                    link.Text = wf.GetEventDescription(item);
                    link.CommandName = item;
                    link.CommandArgument = o.WorkflowInstanceId.Value.ToString();
                }

                i++;
            }
        }

        protected void gvOrders_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            WorkflowBasic wf = WorkflowFactory.Load(new Guid(e.CommandArgument.ToString()));

            try
            {
                wf.SendEvent(e.CommandName, securityManager.authProvider.GetCurrentUser().UserId);
                LoadOrders();
            }
            catch (WorkflowException ex)
            {
                UIHelper.ClientAlert(this, ex.ErrorMessage);
            }
        }
    }
}